package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.sap;

import com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.otw.common.OtwConstant;
import com.alibaba.cirtus.ots.application.adapter.ability.model.Result;
import com.alibaba.cirtus.ots.application.adapter.ability.model.enums.MnSAPStatus;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.HttpTokenUtil;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.HttpUtils;
import com.alibaba.citrus.ots.common.util.SapAndCrmFieldDealUtils;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.otsapplicationadaptersdk.contants.OtsApplicationAdapterSdkConstants;
import com.epoch.app.otsapplicationadaptersdk.mnsapif013ext2.dto.QueryUnConfirmQuantityRequest;
import com.epoch.app.otsapplicationadaptersdk.mnsapif013ext2.dto.QueryUnConfirmQuantityResponse;
import com.epoch.app.otsapplicationadaptersdk.mnsapif013ext2.service.MnSapIf013Ext2Service;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapCommDetail;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapCommResponse;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapCommSDO;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf013Request;
import com.epoch.app.otsapplicationadaptersdk.sapv2.mnsapif013v2.service.MnSapIf013V2Service;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MnSapIf013Ext2ServiceImpl implements MnSapIf013Ext2Service {

    private final Log log = Log.getLogger(MnSapIf013Ext2ServiceImpl.class);

    @Autowired
    private HttpUtils httpUtils;

    @Autowired
    private MnSapIf013V2Service mnSapIf013V2Service;

    /**
     * syncOrder
     *
     * @param mnSapIf013Request
     */
    @Override
    public MnSapCommResponse syncOrder(MnSapIf013Request mnSapIf013Request) {
        log.info("MnSapIf013Ext2ServiceImpl syncOrder request={}", JSON.toJSONString(mnSapIf013Request));
        String receiver = mnSapIf013Request.getMessageHeader().getReceiver();
        if (!"YWZT".equals(receiver)) {
            log.info("MnSapIf013Ext2ServiceImpl#syncOrder skip receiver={}", receiver);
            return getIgnoreResponse(mnSapIf013Request);
        }
        MnSapCommResponse mnSapCommResponse = toBcLink(mnSapIf013Request);
        String allocateOrderId = mnSapIf013Request.getData().get(0).getAllocateOrderId();
        if (StringUtils.isNotBlank(allocateOrderId)) {
            // sap发出的报文有问题，有些报文没有传中台子单号，这种报文转发到013去处理会重复生成明细行，先自己补一下单号
            boolean first = StringUtils.isBlank(mnSapIf013Request.getData().get(0).getModifier());
            if (first) {
                // 问题出在第一次来的报文（没有修改者）
                mnSapIf013Request.getData().get(0).getItems().forEach(r -> {
                    if (StringUtils.isBlank(r.getAllocateOrderLineId())) {
                        r.setAllocateOrderLineId(SapAndCrmFieldDealUtils.generateIdField(r.getOutAllocateOrderLineId()));
                        log.info("MnSapIf013Ext2ServiceImpl#syncOrder fill allocateOrderLineId={} outAllocateOrderLineId={}",
                            r.getAllocateOrderLineId(), r.getOutAllocateOrderLineId());
                    }
                });
            }
        }
        MnSapCommResponse mnSapCommResponse2 = mnSapIf013V2Service.externalUpdateAllocateBySaleOrder(mnSapIf013Request);
        log.info("MnSapIf013Ext2ServiceImpl#mnSapIf013V2Service#externalUpdateAllocateBySaleOrder result={}",
            JSON.toJSONString(mnSapCommResponse2));
        return mnSapCommResponse2;
    }

    private MnSapCommResponse toBcLink(MnSapIf013Request mnSapIf013Request) {
        MnSapCommResponse mnSapCommResponse = new MnSapCommResponse();
        MnSapCommSDO mnSapCommSDO = new MnSapCommSDO();
        try {
            Map<String, String> header = HttpTokenUtil.generateHttpHeader();
            String urlPrefix = OtsApplicationAdapterSdkConstants.urlPrefix();
            String url = urlPrefix + "api/mn_bc_link/syncSapFactoryOrder";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", mnSapIf013Request.getData());
            log.info("MnSapIf013Ext2ServiceImpl syncOrder toBcLink call bc link interface,url:{}, header:{}, " + "param:{}", url,
                header, jsonObject);
            ResponseEntity<Result> post = httpUtils.post(url, header, jsonObject,
                Result.class);
            Result result = post.getBody();
            log.info("MnSapIf013Ext2ServiceImpl syncOrder toBcLink result:{}", JSON.toJSONString(result));
            if (result != null && result.isSuccess()) {
                mnSapCommSDO.setStatus(MnSAPStatus.SUCCESS.getCode());
            } else {
                mnSapCommSDO.setStatus(MnSAPStatus.ERROR.getCode());
                mnSapCommSDO.setErrCode(result != null ? result.getErrorCode() : OtwConstant.ORDER_001_01_01_001);
                mnSapCommSDO.setMessage(result != null ? result.getMessage() : MnSAPStatus.ERROR.getMsg());
            }
        } catch (Exception e) {
            log.error("MnSapIf022V2ServiceImpl syncOrder error", e);
            mnSapCommSDO.setStatus(MnSAPStatus.ERROR.getCode());
            mnSapCommSDO.setErrCode(OtwConstant.ORDER_001_01_01_001);
            mnSapCommSDO.setMessage(MnSAPStatus.ERROR.getMsg());
        }
        List<MnSapCommDetail> items = mnSapIf013Request.getData().stream().map(r -> {
            MnSapCommDetail detail = new MnSapCommDetail();
            detail.setItemKey(r.getHeaderKey());
            detail.setStatus(mnSapCommSDO.getStatus());
            detail.setMessage(mnSapCommSDO.getMessage());
            return detail;
        }).collect(Collectors.toList());
        mnSapCommSDO.setItem(items);
        mnSapCommResponse.setData(Lists.newArrayList(mnSapCommSDO));
        mnSapCommResponse.setMessageId(mnSapIf013Request.getMessageHeader().getMessageId());
        mnSapCommResponse.setInterfacePath(mnSapIf013Request.getMessageHeader().getInterfacePath());
        return mnSapCommResponse;
    }

    /**
     * queryUnConfirmQuantity
     *
     * @param queryUnConfirmQuantityRequest
     */
    @Override
    public QueryUnConfirmQuantityResponse queryUnConfirmQuantity(QueryUnConfirmQuantityRequest queryUnConfirmQuantityRequest) {
        log.info("MnSapIf013Ext2ServiceImpl queryUnConfirmQuantity request={}", JSON.toJSONString(queryUnConfirmQuantityRequest));
        QueryUnConfirmQuantityResponse queryUnConfirmQuantityResponse = new QueryUnConfirmQuantityResponse();
        JSONObject data = new JSONObject();
        try {
            Map<String, String> header = HttpTokenUtil.generateHttpHeader();
            String urlPrefix = OtsApplicationAdapterSdkConstants.urlPrefix();
            String url = urlPrefix + "api/mn_bc_link/unConfirmQuantityStatistics";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("items", queryUnConfirmQuantityRequest.getData());
            log.info(
                "MnSapIf013Ext2ServiceImpl queryUnConfirmQuantity toBcLink call bc link interface,url:{}, header:{}, "
                    + "param:{}", url, header, jsonObject);
            ResponseEntity<Result> post = httpUtils.post(url, header, jsonObject,
                com.alibaba.cirtus.ots.application.adapter.ability.model.Result.class);
            com.alibaba.cirtus.ots.application.adapter.ability.model.Result result = post.getBody();
            log.info("MnSapIf013Ext2ServiceImpl queryUnConfirmQuantity toBcLink result:{}", JSON.toJSONString(result));
            if (result != null && result.isSuccess() && result.getResult() != null) {
                data.put("status", MnSAPStatus.SUCCESS.getCode());
                data.put("items", JSON.parseObject(JSON.toJSONString(result.getResult())).getJSONArray("items"));
            } else {
                data.put("status", MnSAPStatus.ERROR.getCode());
                data.put("errCode", result != null ? result.getErrorCode() : OtwConstant.ORDER_001_01_01_001);
                data.put("message", result != null ? result.getMessage() : MnSAPStatus.ERROR.getMsg());
            }
        } catch (Exception e) {
            log.error("MnSapIf022V2ServiceImpl queryUnConfirmQuantity error", e);
            data.put("status", MnSAPStatus.ERROR.getCode());
            data.put("errCode", OtwConstant.ORDER_001_01_01_001);
            data.put("message", MnSAPStatus.ERROR.getMsg());
        }
        queryUnConfirmQuantityResponse.setData(data);
        return queryUnConfirmQuantityResponse;
    }

    private MnSapCommResponse getIgnoreResponse(MnSapIf013Request mnSapIf013Request) {
        MnSapCommResponse mnSapCommResponse = new MnSapCommResponse();
        MnSapCommSDO mnSapCommSDO = new MnSapCommSDO();
        mnSapCommSDO.setStatus(MnSAPStatus.ERROR.getCode());
        mnSapCommSDO.setErrCode(OtwConstant.ORDER_001_01_01_001);
        mnSapCommSDO.setMessage("receiver非'YWZT'，已忽略处理");
        List<MnSapCommDetail> items = mnSapIf013Request.getData().stream().map(r -> {
            MnSapCommDetail detail = new MnSapCommDetail();
            detail.setItemKey(r.getHeaderKey());
            detail.setStatus(mnSapCommSDO.getStatus());
            detail.setMessage(mnSapCommSDO.getMessage());
            return detail;
        }).collect(Collectors.toList());
        mnSapCommSDO.setItem(items);
        mnSapCommResponse.setData(Lists.newArrayList(mnSapCommSDO));
        mnSapCommResponse.setMessageId(mnSapIf013Request.getMessageHeader().getMessageId());
        mnSapCommResponse.setInterfacePath(mnSapIf013Request.getMessageHeader().getInterfacePath());
        return mnSapCommResponse;
    }
}
